﻿
#ifndef ModelEffectCollection_h
#define ModelEffectCollection_h

#include <System/Collections/Generic/IReadOnlyCollection.h>
#include <System/Collections/Generic/KeyNotFoundException.h>
#include <System/Collections/IEnumerator.h>

#include <Riccsson/Xna/Framework/Graphics/Effect/Effect.h>

namespace Riccsson
{
	namespace Xna
	{
		namespace Framework
		{
			namespace Graphics
			{
				// Summary:
				//     Represents a collection of effects associated with a model.
				class ModelEffectCollection sealed
					: Riccsson::System::Collections::ObjectModel::ReadOnlyCollection<GC_PTR<Effect>>
				{
					
#pragma region Enumerator.
					// Summary:
					//     Provides the ability to iterate through the bones in an ModelEffectCollection.
					struct Enumerator
						: public Riccsson::System::Collections::Generic::IEnumerator<GC_PTR<Effect>>
					{
						Riccsson::System::Collections::Generic::List<GC_PTR<Effect>>::Enumerator* enumerator;
						bool disposed;

						/*internal*/ Enumerator(Riccsson::System::Collections::Generic::List<GC_PTR<Effect>>* list)
						{
							enumerator = (Riccsson::System::Collections::Generic::List<GC_PTR<Effect>>::Enumerator*)list->GetEnumerator();
							disposed = false;
						}
						
						// Summary:
						//     Gets the current element in the ModelEffectCollection.
						public: override PROP3_GET(GC_PTR<Effect>, Current)
						{
							return enumerator->Current;
						}

						// Summary:
						//     Immediately releases the unmanaged resources used by this object.
						public: void Dispose()
						{
							if (!disposed)
							{
								enumerator->Dispose();
								disposed = true;
							}
						}
						//
						// Summary:
						//     Advances the enumerator to the next element of the ModelEffectCollection.
						public: bool MoveNext() { return enumerator->MoveNext(); }

						#pragma region IEnumerator Members

						//GC_PTR<Ricssson::System::object> IEnumerator::Current
						//{
						//	get { return Current; }
						//}

						void Reset()
						{
							Riccsson::System::Collections::IEnumerator* resetEnumerator = (Riccsson::System::Collections::IEnumerator*)enumerator;
							resetEnumerator->Reset ();
							enumerator = (Riccsson::System::Collections::Generic::List<GC_PTR<Effect>>::Enumerator*)resetEnumerator;
						}

						#pragma endregion
					};

#pragma endregion

				public: ModelEffectCollection(Riccsson::System::Collections::Generic::IList<GC_PTR<Effect>>* list)
						: Riccsson::System::Collections::ObjectModel::ReadOnlyCollection<GC_PTR<Effect>>(list)
					{

					}

					/*internal*/ ModelEffectCollection()
						: Riccsson::System::Collections::ObjectModel::ReadOnlyCollection<GC_PTR<Effect>>(
							new Riccsson::System::Collections::Generic::List<GC_PTR<Effect>>())
					{
					}
		
					//ModelMeshPart needs to be able to add to ModelMesh's effects list
					private: /*internal*/ void Add(Effect* item)
					{
						Items.get()->Add (item);
					}
					private: /*internal*/ void Remove(Effect* item)
					{
						Items.get()->Remove (item);
					}

					// Summary:
					//     Returns a ModelEffectCollection.Enumerator that can iterate through a ModelEffectCollection.
					public: ModelEffectCollection::Enumerator* GetEnumerator()
					{
						return new ModelEffectCollection::Enumerator((Riccsson::System::Collections::Generic::List<GC_PTR<Effect>>*)*Items.get());
					}

				};
			}
		}
	}
}

#endif